package com.lyn.pluginbazaar.thread;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.SneakyThrows;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Luck
 * @date 2022/9/7:14:42
 */
public class PC {
    public static void main(String[] args) {
        Monitor monitor = new Monitor();
        for (int i = 1; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        monitor.offer(RandomUtil.randomString(10));
                        ThreadUtil.sleep(1000);
                    }
                }
            }, "producer->" + i).start();
        }
        for (int i = 1; i < 4; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        monitor.remove();
                        ThreadUtil.sleep(2000);
                    }
                }
            }, "consumer->" + i).start();
        }
    }

    static class Monitor {
        Queue<String> queue = new LinkedList<>();
        private AtomicInteger count = new AtomicInteger();
        int max = 5;

        @SneakyThrows
        synchronized void offer(String item) {
            while (max == queue.size()) {
                System.out.println("由于队列满了" + Thread.currentThread().getName() + "被阻塞了");
                System.out.println(Thread.currentThread().getName() + "当前队列数量" + count.get());
                this.wait();
            }
            queue.offer(item);
            count.incrementAndGet();
            System.out.println(Thread.currentThread().getName() + "生产了" + item);
            this.notifyAll();
        }

        @SneakyThrows
        synchronized String remove() {
            while (queue.isEmpty()) {
                System.out.println("由于队列为空" + Thread.currentThread().getName() + "被阻塞了");
                System.out.println(Thread.currentThread().getName() + "当前队列数量" + count.get());
                this.wait();
            }
            String item = queue.poll();
            System.out.println(Thread.currentThread().getName() + "消费了" + item);
            count.decrementAndGet();
            this.notifyAll();
            return item;
        }
    }
}
